/*-
 * TOA.java          TP-Type-Of-Address
 *
 * $LastChangedBy: stein $
 * $LastChangedRevision: 98 $
 * $LastChangedDate: 2007-02-20 15:18:26 +0000 (Tue, 20 Feb 2007) $
 * $HeadURL: svn://localhost/SMS/src/com/googlecode/attention/sms/pdu/TOA.java $
 *
 * Copyright (c) 2007, Stein Gunnar Bakkeby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Stein Gunnar Bakkeby nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.attention.sms.pdu;

import com.googlecode.attention.util.IntValue;

import static com.googlecode.attention.util.bit.ByteBitValues.*;

/**
 * TP-Type-Of-Address (TP-TOA).
 * <BR>
 * <BR>Address fields used by SM-RL are specified in 3GPP TS 24.011 and
 * 3GPP TS 29.002. Each address field of the SM-TL consists of the following
 * sub-fields: An Address-Length field of one octet, a Type-of-Address field
 * of one octet, and one Address-Value field of variable length.
 * <BR>
 * <BR>The Address-Length field is an integer representation of the number
 * of useful semi-octets within the Address-Value field, i.e. excludes any
 * semi octet containing only fill bits.
 * <BR>
 * <BR>The Type-of-Address field format is as follows:
 * <BR>[1][Type-of-Number (3)][Numbering-plan-identification (4)]
 * <BR>
 * <BR>Type-of-number:
 * <BR>
 * <BR><TABLE>
 * <TR><TD>6</TD><TD>5</TD><TD>4</TD><TD></TD></TR>
 * <TR><TD>0</TD><TD>0</TD><TD>0</TD><TD>Unknown 1)</TD></TR>
 * <TR><TD>0</TD><TD>0</TD><TD>1</TD><TD>International number 2)</TD></TR>
 * <TR><TD>0</TD><TD>1</TD><TD>0</TD><TD>National number 3)</TD></TR>
 * <TR><TD>0</TD><TD>1</TD><TD>1</TD><TD>Network specific number 4)</TD></TR>
 * <TR><TD>1</TD><TD>0</TD><TD>0</TD><TD>Subscriber number 5)</TD></TR>
 * <TR><TD>1</TD><TD>0</TD><TD>1</TD><TD>Alphanumeric, (coded according to 3GPP TS 23.038 [9] GSM 7-bit default alphabet)</TD></TR>
 * <TR><TD>1</TD><TD>1</TD><TD>0</TD><TD>Abbreviated number</TD></TR>
 * <TR><TD>1</TD><TD>1</TD><TD>1</TD><TD>Reserved for extension</TD></TR>
 * </TABLE>
 * <BR>
 * <BR>The MS shall interpret reserved values as "Unknown" but shall
 * store them exactly as received.
 * <BR>
 * <BR>The SC may reject messages with a type of number containing
 * a reserved value or one which is not supported.
 * <BR>
 * <BR>Reserved values shall not be transmitted by an SC conforming to
 * this version of the specification.
 * <BR>
 * <BR> 1) "Unknown" is used when the user or network has no a priori
 * information about the numbering plan. In this case, the Address-Value
 * field is organised according to the network dialling plan, e.g. prefix
 * or escape digits might be present.
 * <BR>
 * <BR> 2) The international format shall be accepted also when the message
 * is destined to a recipient in the same country as the MSC or as the SGSN.
 * <BR>
 * <BR> 3) Prefix or escape digits shall not be included.
 * <BR>
 * <BR> 4) "Network specific number" is used to indicate
 * administration/service number specific to the serving network, e.g.
 * used to access an operator.
 * <BR>
 * <BR> 5) "Subscriber number" is used when a specific short number
 * representation is stored in one or more SCs as part of a higher layer
 * application. (Note that "Subscriber number" shall only be used in
 * connection with the proper PID referring to this application).
 * <BR>
 * <BR>
 * <BR>Numbering-plan-identification:
 * <BR>
 * <BR>
 * <TABLE>
 * <TR><TD>3</TD><TD>2</TD><TD>1</TD><TD>0</TD><TD></TD></TR>
 * <TR><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>Unknown</TD></TR>
 * <TR><TD>0</TD><TD>0</TD><TD>0</TD><TD>1</TD><TD>ISDN/telephone numbering plan (E.164/E.163)</TD></TR>
 * <TR><TD>0</TD><TD>0</TD><TD>1</TD><TD>1</TD><TD>Data numbering plan (X.121)</TD></TR>
 * <TR><TD>0</TD><TD>1</TD><TD>0</TD><TD>0</TD><TD>Telex numbering plan</TD></TR>
 * <TR><TD>0</TD><TD>1</TD><TD>0</TD><TD>1</TD><TD>Service Centre Specific plan 1)</TD></TR>
 * <TR><TD>0</TD><TD>1</TD><TD>1</TD><TD>0</TD><TD>Service Centre Specific plan 1)</TD></TR>
 * <TR><TD>1</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>National numbering plan</TD></TR>
 * <TR><TD>1</TD><TD>0</TD><TD>0</TD><TD>1</TD><TD>Private numbering plan</TD></TR>
 * <TR><TD>1</TD><TD>0</TD><TD>1</TD><TD>0</TD><TD>ERMES numbering plan (ETSI DE/PS 3 01-3)</TD></TR>
 * <TR><TD>1</TD><TD>1</TD><TD>1</TD><TD>1</TD><TD>Reserved for extension</TD></TR>
 * <TR><TD></TD><TD></TD><TD></TD><TD></TD><TD>All other values are reserved.</TD></TR>
 * </TABLE>
 * <BR>
 * <BR> 1) "Service Centre specific number" is used to indicate a numbering
 * plan specific to External Short Message Entities attached to the SMSC.
 * <BR>
 * <BR>For Type-of-number = 101 bits 3,2,1,0 are reserved and shall be
 * transmitted as 0000. Note that for addressing any of the entities SC,
 * MSC, SGSN or MS, Numbering-plan-identification = 0001 shall always be used.
 * However, for addressing the SME, any specified Numbering-plan-identification
 * value may be used.
 * <BR>
 * <BR>The MS shall interpret reserved values as "Unknown" but shall store
 * them exactly as received.
 * <BR>
 * <BR>The SC may reject messages with a type of number containing a reserved
 * value or one which is not supported.
 * <BR>
 * <BR>Reserved values shall not be transmitted by an SC conforming to this
 * version of the specification. Within the Address-Value field, either a
 * semi-octet or an alphanumeric1) representation applies.
 * <BR>
 * <BR>The maximum length of the full address field (Address-Length,
 * Type-of-Address and Address-Value) is 12 octets.
 * <BR> 1) Applies only to addressing at the SM-TL.
 * <BR>
 * <BR>
 * <BR>
 * <BR>The Type-of-Address octet indicates the format of a phone number.
 * The most common value of this octet is 91 hex (10010001 bin),
 * which indicates international format. A phone number in international
 * format looks like 46708251358 (where the country code is 46).
 * In the national (or unknown) format the same phone number would
 * look like 0708251358. The international format is the most generic,
 * and it has to be accepted also when the message is destined to a
 * recipient in the same country as the MSC or as the SGSN.
 * <BR><BR>
 * The TP-Originating-Address field and the TP-Destination-Address field
 * are formatted according to the formatting rules of address fields.
 * The first "#" encountered in TP-OA/DA indicates where the address for
 * SMSC routing purposes is terminated. Additional "*"s or "#"s can be
 * present in the following digits, and all these digits including the
 * first "#" are subaddress digits.
 *
 * <BR><A HREF="http://www.dreamfabric.com/sms/type_of_address.html">
 *              http://www.dreamfabric.com/sms/type_of_address.html</A>
 *
 * @author Stein Gunnar Bakkeby
 */
public class TOA extends IntValue {

  /* Static field values */
  /* TON: Type of Number. */
  /**
   * Unknown. This is used when the user or network has no a priori
   * information about the numbering plan. In this case, the Address-Value
   * field is organised according to the network dialling plan, e.g. prefix
   * or escape digits might be present.
   */
  public static final int TON_UNKNOWN = 0;
  /**
   * The international format shall be accepted also when the message is
   * destined to a recipient in the same country as the MSC or as the SGSN.
   */
  public static final int TON_INTERNATIONAL_NUMBER = 0x10; //B4;
  /** National number. Prefix or escape digits shall not be included. */
  public static final int TON_NATIONAL_NUMBER = 0x20; //B5;
  /**
   * Network specific number. This is used to indicate administration/service
   * number specific to the serving network, e.g. used to access an operator.
   */
  public static final int TON_NETWORK_SPECIFIC_NUMBER = 0x30; //B5|B4;
  /**
   * Subscriber number. This is used when a specific short number
   * representation is stored in one or more SCs as part of a higher
   * layer application. (Note that "Subscriber number" shall only be used
   * in connection with the proper PID referring to this application).
   */
  public static final int TON_SUBSCRIBER_NUMBER = 0x40; //B6;
  /** 
   * Alphanumeric, (coded according to 3GPP TS 23.038
   * GSM 7-bit default alphabet)).
   */
  public static final int TON_ALPHANUMERIC = 0x50; //B6|B4;
  /** Abbreviated number. */
  public static final int TON_ABBREVATED_NUMBER = 0x60; //B6|B5;
  /** Reserved for extension. */
  public static final int TON_RESERVED = 0x70; //B6|B5|B4;
  
  /* NPI: Numbering Plan Identification. */
  /** Unknown. */
  public static final int NPI_UNKNOWN   = 0; //B0
  /** ISDN/telephone numbering plan (E.164/E.163). */
  public static final int NPI_ISDN      = 1; //B0
  /** Data numbering plan (X.121). */
  public static final int NPI_DATA      = 3; //B1|B0
  /** Telex numbering plan. */
  public static final int NPI_TELEX     = 4; //B2
  /**
   * "Service Centre specific number" is used to indicate a numbering plan
   * specific to External Short Message Entities attached to the SMSC.
   * <BR>
   * <BR>Binary value: 0101
   */
  public static final int NPI_SCSP_0101 = 5; //B2|B0
  /**
   * "Service Centre specific number" is used to indicate a numbering plan
   * specific to External Short Message Entities attached to the SMSC.
   * <BR>
   * <BR>Binary value: 0110
   */  
  public static final int NPI_SCSP_0110 = 6; //B2|B1
  /** National numbering plan. */
  public static final int NPI_NATIONAL  = 8;
  /** Private numbering plan. */
  public static final int NPI_PRIVATE   = 9;
  /** ERMES numbering plan (ETSI DE/PS 3 01-3). */
  public static final int NPI_ERMES     = 10;
  /** Reserved for extension. */
  public static final int NPI_RESERVED  = 15;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_0010 = 2;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_0111 = 7;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_1011 = 11;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_1100 = 12;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_1101 = 13;
  /** Reserved for extension. */
  public static final int NPI_RESERVED_1110 = 14;
  /* End static field values */

  /**
   * Default constructor, creates a TOA with the most common numbering
   * information, which is international format with ISDN numbering
   * plan identification.
   */
  public TOA() {
    value = B7|TON_INTERNATIONAL_NUMBER|NPI_ISDN; // 0x91: B7|B4|B0
  }

  /**
   * Inherited constructor from IntValue.
   * @param value The value of this object
   */
  public TOA(final int value) {
    super(value);
  }
  
  /**
   * Inherited constructor from IntValue.
   * @param hex The value of this object in hex
   */
  public TOA(final String hex) {
    super(hex);
  }
  
  /* Get methods */
  /**
   * Returns the Type of Number binary value.
   *
   * @return The binary value of Type of Number.
   */
  public int getTypeOfNumber() {
    return value & 0x70; //(B6|B5|B4);
  }

  /**
   * Returns the Numbering Plan Identification binary value.
   *
   * @return The binary value of Numbering Plan Identification.
   */
  public int getNumPlanIdent() {
    return value & 0xF; //(B3|B2|B1|B0);
  }
  
  /**
   * This will set the Type-of-Number.
   * 
   * @param ton See TON_ static field values
   * @throws IllegalArgumentException If value is not recognised
   */
  public void setTypeOfNumber(final int ton) {
    switch (ton) {
    case TON_ABBREVATED_NUMBER:
    case TON_ALPHANUMERIC:
    case TON_INTERNATIONAL_NUMBER:
    case TON_NATIONAL_NUMBER:
    case TON_NETWORK_SPECIFIC_NUMBER:
    case TON_SUBSCRIBER_NUMBER:
    case TON_UNKNOWN:
    case TON_RESERVED:
      value &= 0x8F; // (B3|B2|B1|B0) to keep
      value |= ton; 
      break;
      
    default:
      throw new IllegalArgumentException(
          "Use TON_ static field values in TOA!");
    }
  }
  
  /**
   * This will set the Numbering-plan-identifier.
   * 
   * @param npi See NPI_ static field values
   * @throws IllegalArgumentException If value is not recognised
   */
  public void setNumPlanIdent(final int npi) throws IllegalArgumentException {
    switch (npi) {
    case NPI_DATA:
    case NPI_ERMES:
    case NPI_ISDN:
    case NPI_NATIONAL:
    case NPI_PRIVATE:
    case NPI_SCSP_0101:
    case NPI_SCSP_0110:
    case NPI_TELEX:
    case NPI_UNKNOWN:
    case NPI_RESERVED:
    case NPI_RESERVED_0010:
    case NPI_RESERVED_0111:
    case NPI_RESERVED_1011:
    case NPI_RESERVED_1100:
    case NPI_RESERVED_1101:
    case NPI_RESERVED_1110:
      value &= 0xF0; // (B7|B6|B5|B4) to keep
      value |= npi;
      break;
      
    default:
      throw new IllegalArgumentException(
      "Use NPI_ static field values in TOA!");
    }
  }
  
  /**
   * @return Integer.toString(value);
   */
  public String toString() {
    return Integer.toString(value);
  }
  
  @Override
  public boolean equals(final Object another) {
    if (another instanceof TOA) {
      return value == ((TOA)another).value;
    }
    return false;
  }
}